package com.tansun.easycare.rule.ml.algorithm.web;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.io.output.DeferredFileOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.alibaba.fastjson.JSONObject;
import com.tansun.easycare.core.utils.StringUtils;
import com.tansun.easycare.core.web.BaseController;
import com.tansun.easycare.rule.ml.algorithm.service.IAlgorthmService;
import com.tansun.easycare.rule.ml.model.entity.MlDataModel;
import com.tansun.easycare.rule.ml.model.service.MlDataModelService;


/**
 * 文件处理控制类
 * @author xch
 * @version 2018-08-24
 */
@Controller
@RequestMapping(value = "/file")
public class FileController extends BaseController {

	private Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	private MlDataModelService mlDataModelService;

	@Autowired
	private IAlgorthmService iAlgrthmService;
	
	@ModelAttribute
	public MlDataModel get(@RequestParam(required=false) String id) {
		MlDataModel entity = null;
		if (StringUtils.isNotBlank(id)){
			entity = mlDataModelService.get(id);
		}
		if (entity == null){
			entity = new MlDataModel();
		}
		return entity;
	}
	
	/**
	 * 上传训练文件
	 * 
	 * @param request
	 * @param model
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value="upload")
	public @ResponseBody JSONObject upload(MlDataModel mlDataModel,String apply,HttpServletRequest request) {
		JSONObject res = new JSONObject();
		try {
			MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
			CommonsMultipartFile multipartFile = (CommonsMultipartFile)multipartRequest.getFile("file");	/** 页面控件的文件流 **/
			
			String[] fileNameSplit = multipartFile.getOriginalFilename().split("\\.");	/** 获取文件的后缀 **/
			String suffix = fileNameSplit[fileNameSplit.length-1];
			String name = fileNameSplit[0];
			
			Map<String,String> inputMap = new HashMap<String,String>();
			inputMap.put("suffix",suffix);
			inputMap.put("apply",apply);
			inputMap.put("name",name);
			inputMap.put("modelId",String.valueOf(mlDataModel.getModelId()));
			
			String savepath = null;
			DiskFileItem diskFileItem = (DiskFileItem)multipartFile.getFileItem();
			if (diskFileItem.isInMemory()){
				DeferredFileOutputStream deferredFileOutputStream = (DeferredFileOutputStream)diskFileItem.getOutputStream();
				byte[] byteArr = deferredFileOutputStream.getData();
				savepath = (String) iAlgrthmService.upload(byteArr,multipartFile.getOriginalFilename(),inputMap).getResponse().get("savepath");
			}else{
				File localfile = diskFileItem.getStoreLocation();
				//文件上传到python服务
				savepath = (String) iAlgrthmService.upload(localfile,inputMap).getResponse().get("savepath");
				
			}
			
			

			if ("train".equals(apply)){
				//模型更新
				mlDataModel.setDataFile(savepath);
				mlDataModelService.updateDataFile(mlDataModel);
				
				String url = "/ml/workflows/goToSite?currentSite=dataInput"+
				"&modelId="+mlDataModel.getModelId()+
				"&modelName="+mlDataModel.getModelName()+
				"&algorithmType="+mlDataModel.getAlgorithmType()+
				"&dataFile="+savepath;
				
				res.put("status", "success");
				res.put("savepath", savepath);
				res.put("url", url);
				logger.info("file upload success!");
			}else if ("test".equals(apply)){
				res.put("status", "success");
				res.put("savepath", savepath);
			}else{
				res.put("status", "fail");
				res.put("content", "上传参数错误!");
			}
		} catch (Exception e) {
			e.printStackTrace();
			res.put("status", "fail");
			res.put("content", e.getMessage());
		}
		return res;
		
	}
	
	/**
	 * 下载文件
	 * @param session
	 * @param request
	 * @param response
	 */
	@RequestMapping(method = RequestMethod.GET, value = "download")
	@ResponseStatus(HttpStatus.OK)
	public void download(HttpSession session, HttpServletRequest request, HttpServletResponse response) {
		String savepath = request.getParameter("savepath");
		String[] arr = savepath.split("/");
		try {
			String fileName = new String(arr[arr.length-1].getBytes(), "ISO-8859-1");
			byte[] bytes = iAlgrthmService.downloadFile(savepath);
			//response.reset();
			response.addHeader("Content-Disposition", "attachment;filename="+ fileName);
			response.addHeader("Content-Length", "" + bytes.length);
			response.setContentType("txt");
			OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
			response.setContentType("application/octet-stream");
			toClient.write(bytes);
			toClient.flush();
			toClient.close();
	   } catch (Exception e) {
		   e.printStackTrace();
		   try{
			   //response.reset();
			   String fileName = new String(arr[arr.length-1].getBytes(), "ISO-8859-1");
			   response.addHeader("Content-Disposition", "attachment;filename="+ fileName);
			   response.addHeader("Content-Length", "" + e.getMessage().getBytes().length);
			   response.setContentType("txt");
			   OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
			   response.setContentType("application/octet-stream");
			   toClient.write(e.getMessage().getBytes());
			   toClient.flush();
			   toClient.close();
		   }catch(Exception ex){
			   ex.printStackTrace();
		   }
	   }
	}
}
